import json
import atexit
import logging
import os
from pathlib import Path
import pickle
from typing import List, Literal
from ..config import data_storage_path

CACHE_PATH = data_storage_path("cache")


class Caching:

    def check_cache(self, category: str, name: str):
        cache_path = self.cache_item_path(category, name)
        return os.path.exists(cache_path)
    
    def get_cache(self, category: str, name: str):
        if self.check_cache(category, name):
            return self.load_cache(category, name)
        else:
            return None

    def load_cache(self, category: str, name: str):
        cache_path = self.cache_item_path(category, name)
        if cache_path.endswith(".json"):
            with open(cache_path, "r", encoding="utf-8") as f:
                return json.load(f)
        elif cache_path.endswith(".pkl"):
            with open(cache_path, "rb") as f:
                return pickle.load(f)
        else:
            raise ValueError(f"Unknown file extension for cache file: {cache_path}")

    def cache_item_path(self, category: str, name: str) -> str:
        return os.path.join(CACHE_PATH, category, name)

    def save_cache(
        self,
        category: str,
        name: str,
        data: str,
    ):
        """
        :category: str, category of the cache, must be a valid identifier.
            Indicating a new folder to store caches
        :name: str, name of the cache, must be a valid identifier.
            Indicating a new file to store cache
        :data: str, data to be stored
        """
        # assert category.isidentifier()
        # assert name.isidentifier()
        cache_category_path = os.path.join(CACHE_PATH, category)
        cache_item_path = self.cache_item_path(category, name)
        if not os.path.exists(cache_category_path):
            os.makedirs(cache_category_path, exist_ok=True)
        if name.endswith(".json"):
            with open(cache_item_path, "w", encoding="utf-8") as f:
                json.dump(data, f, indent=2, ensure_ascii=False)
        elif name.endswith(".pkl"):
            with open(cache_item_path + ".pkl", "wb") as f:
                pickle.dump(data, f)
        else:
            raise ValueError(f"Invalid type {type}")
